﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.Screens.GameStateScreenManager
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using System;
using System.Collections.Generic;
using System.Reflection;
using TaleWorlds.Core;
using TaleWorlds.Engine;
using TaleWorlds.ScreenSystem;

#nullable disable
namespace TaleWorlds.MountAndBlade.View.Screens
{
  public class GameStateScreenManager : IGameStateManagerListener
  {
    private Dictionary<System.Type, System.Type> _screenTypes;

    private GameStateManager GameStateManager => GameStateManager.Current;

    public GameStateScreenManager()
    {
      this._screenTypes = new Dictionary<System.Type, System.Type>();
      Assembly[] viewAssemblies = GameStateScreenManager.GetViewAssemblies();
      this.CheckAssemblyScreens(typeof (GameStateScreen).Assembly);
      foreach (Assembly assembly in viewAssemblies)
        this.CheckAssemblyScreens(assembly);
      ManagedOptions.OnManagedOptionChanged += new ManagedOptions.OnManagedOptionChangedDelegate(this.OnManagedOptionChanged);
    }

    private void OnManagedOptionChanged(
      ManagedOptions.ManagedOptionsType changedManagedOptionsType)
    {
      if (changedManagedOptionsType != ManagedOptions.ManagedOptionsType.ForceVSyncInMenus)
        return;
      if (!BannerlordConfig.ForceVSyncInMenus)
      {
        Utilities.SetForceVsync(false);
      }
      else
      {
        if (!this.GameStateManager.ActiveState.IsMenuState)
          return;
        Utilities.SetForceVsync(true);
      }
    }

    private void CheckAssemblyScreens(Assembly assembly)
    {
      foreach (System.Type type in assembly.GetTypesSafe())
      {
        object[] customAttributesSafe = type.GetCustomAttributesSafe(typeof (GameStateScreen), false);
        if (customAttributesSafe != null && customAttributesSafe.Length != 0)
        {
          foreach (GameStateScreen gameStateScreen in customAttributesSafe)
          {
            if (this._screenTypes.ContainsKey(gameStateScreen.GameStateType))
              this._screenTypes[gameStateScreen.GameStateType] = type;
            else
              this._screenTypes.Add(gameStateScreen.GameStateType, type);
          }
        }
      }
    }

    public static Assembly[] GetViewAssemblies()
    {
      List<Assembly> assemblyList = new List<Assembly>();
      Assembly assembly1 = typeof (GameStateScreen).Assembly;
      foreach (Assembly assembly2 in AppDomain.CurrentDomain.GetAssemblies())
      {
        foreach (object referencedAssembly in assembly2.GetReferencedAssemblies())
        {
          if (referencedAssembly.ToString() == assembly1.GetName().ToString())
          {
            assemblyList.Add(assembly2);
            break;
          }
        }
      }
      return assemblyList.ToArray();
    }

    public ScreenBase CreateScreen(GameState state)
    {
      System.Type type = (System.Type) null;
      if (!this._screenTypes.TryGetValue(state.GetType(), out type))
        return (ScreenBase) null;
      return Activator.CreateInstance(type, (object) state) as ScreenBase;
    }

    public void BuildScreens()
    {
      int num = 0;
      foreach (GameState gameState in this.GameStateManager.GameStates)
      {
        ScreenBase screen = this.CreateScreen(gameState);
        gameState.RegisterListener(screen as IGameStateListener);
        if (screen != null)
        {
          if (num == 0)
            ScreenManager.CleanAndPushScreen(screen);
          else
            ScreenManager.PushScreen(screen);
        }
        ++num;
      }
    }

    void IGameStateManagerListener.OnCreateState(GameState gameState)
    {
      ScreenBase screen = this.CreateScreen(gameState);
      gameState.RegisterListener(screen as IGameStateListener);
    }

    void IGameStateManagerListener.OnPushState(GameState gameState, bool isTopGameState)
    {
      if (!gameState.IsMenuState)
        Utilities.ClearOldResourcesAndObjects();
      if (gameState.IsMenuState && BannerlordConfig.ForceVSyncInMenus)
        Utilities.SetForceVsync(true);
      else if (!gameState.IsMenuState)
        Utilities.SetForceVsync(false);
      ScreenBase listenerOfType;
      if ((listenerOfType = gameState.GetListenerOfType<ScreenBase>()) == null)
        return;
      if (isTopGameState)
        ScreenManager.CleanAndPushScreen(listenerOfType);
      else
        ScreenManager.PushScreen(listenerOfType);
    }

    void IGameStateManagerListener.OnPopState(GameState gameState)
    {
      if (!gameState.IsMenuState)
        Utilities.ClearOldResourcesAndObjects();
      if (gameState.IsMenuState && BannerlordConfig.ForceVSyncInMenus)
        Utilities.SetForceVsync(false);
      if (this.GameStateManager.ActiveState != null && this.GameStateManager.ActiveState.IsMenuState && BannerlordConfig.ForceVSyncInMenus)
        Utilities.SetForceVsync(true);
      ScreenManager.PopScreen();
    }

    void IGameStateManagerListener.OnCleanStates() => ScreenManager.CleanScreens();

    void IGameStateManagerListener.OnSavedGameLoadFinished() => this.BuildScreens();
  }
}
